package com.ilia.rubik;

import java.util.ArrayList;
import java.util.List;

import com.ilia.util.timer.ITimer;

public class PossibleMoves {
	
	public PossibleMoves(ITimer timer) {
		this.timer = timer;
	}
	
	ITimer timer;
	char[][][][] prmCache;
	char[] possible_moves = { 'F', 'f', 'T', 't', 'R', 'r', 'D', 'd', 'L', 'l', 'B', 'b' };


	int findMoveId(char move) {
		for (int i = 0; i < possible_moves.length; i++) {
			char possible_move = possible_moves[i];
			if (possible_move == move)
				return i;
		}
		throw new IllegalArgumentException("wrong move: " + move);
	}

	void computePRM() {
		prmCache = new char['z']['z']['z'][];

		char[] pattern = null;// new char[3];

		List pt = new ArrayList();

		for (int i = 0; i < possible_moves.length + 1; i++) {

			char first_possible_move = (i < possible_moves.length) ? possible_moves[i] : ' ';

			for (int j = 0; j < possible_moves.length + 1; j++) {
				char second_possible_move = (j < possible_moves.length) ? possible_moves[j] : ' ';
				for (int k = 0; k < possible_moves.length + 1; k++) {
					char third_possible_move = (k < possible_moves.length) ? possible_moves[k] : ' ';
					pt.clear();
					if (first_possible_move != ' ')
						pt.add(new Character(first_possible_move));
					if (second_possible_move != ' ')
						pt.add(new Character(second_possible_move));
					if (third_possible_move != ' ')
						pt.add(new Character(third_possible_move));

					pattern = Cube.toChars(pt);

					char[] pm = possibleRightMoves(pattern);

					prmCache[first_possible_move][second_possible_move][third_possible_move] = pm;
				}
			}
		}
	}
	
	char[] cachedPossibleRightMoves(char[] moves, int length) {
		// timer.startTimer("PRM");
		char first_move;
		char second_move;
		char third_move;

		switch (length) {
		case 0:
			first_move = ' ';
			second_move = ' ';
			third_move = ' ';
			break;
		case 1:
			first_move = ' ';
			second_move = ' ';
			third_move = moves[length - 1];
			break;
		case 2:
			first_move = ' ';
			second_move = moves[length - 2];
			third_move = moves[length - 1];
			break;
		default:
			first_move = moves[length - 3];
			second_move = moves[length - 2];
			third_move = moves[length - 1];
			break;

		}

		char[] pm = prmCache[first_move][second_move][third_move];
		return pm;

	}

	char[] possibleRightMoves(char[] moves) {
		timer.startTimer("PRM");
		List prmList = new ArrayList();

		for (int i = 0; i < possible_moves.length; i++) {
			char possible_move = possible_moves[i];
			boolean ok = true;
			if ((moves.length >= 1) && (possible_move == Cube.inverse_move(moves[moves.length - 1]))) {
				ok = false;
			}
			if ((moves.length >= 2)
					&& (possible_move == moves[moves.length - 1])
					&& (possible_move == moves[moves.length - 2])
					) {
				ok = false;
			}

			if (ok) {
				prmList.add(new Character(possible_move));
			}
		}
		char[] result = Cube.toChars(prmList);
		timer.stopTimer("PRM");

		return result;
	}


}
